package com.rc.evcharger.service.order;

import com.rc.evcharger.common.dto.ChargeBalaceDto;
import com.rc.evcharger.common.utils.BeanUtil;
import com.rc.evcharger.common.utils.DateHelper;
import com.rc.evcharger.mapper.elec.ElecGunMapper;
import com.rc.evcharger.mapper.elec.ElecPileMapper;
import com.rc.evcharger.mapper.elec.ElecStationPriceMapper;
import com.rc.evcharger.mapper.order.OrderDetailMapper;
import com.rc.evcharger.mapper.order.OrderInfoMapper;
import com.rc.evcharger.model.elec.ElecGun;
import com.rc.evcharger.model.elec.ElecPile;
import com.rc.evcharger.model.elec.ElecStationPrice;
import com.rc.evcharger.model.order.OrderDetail;
import com.rc.evcharger.model.order.OrderDetailExample;
import com.rc.evcharger.model.order.OrderInfo;
import com.rc.evcharger.service.elec.ElecStationPriceService;
import com.rc.evcharger.service.handle.ChargePriceHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;
import java.util.List;

/**
 * Created by sven on 2019/09/23.
 */
@Service
public class OrderDetailServiceImpl implements OrderDetailService {

    private static Logger logger = LogManager.getLogger(OrderDetailServiceImpl.class);

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private ElecPileMapper elecPileMapper;

    @Autowired
    private ElecGunMapper elecGunMapper;

    @Autowired
    private ElecStationPriceMapper elecStationPriceMapper;

    @Autowired
    private ChargePriceHandler chargePriceHandler;

    @Autowired
    private ElecStationPriceService elecStationPriceService;

    @Override
    public OrderDetailMapper getMapper() {
        return orderDetailMapper;
    }


    @Override
    public List<OrderDetail> queryByOrderId(Long orderId) {
        return orderDetailMapper.listByOrderId(orderId);
    }

    @Override
    public OrderDetail selectLastByOrderId(Long orderId) {
        OrderDetailExample orderDetailExample = new OrderDetailExample();
        orderDetailExample.createCriteria().andOrderIdEqualTo(orderId);
        orderDetailExample.setOrderByClause(" order_id desc limit 1");

        List<OrderDetail> orderDetails = orderDetailMapper.selectByExample(orderDetailExample);
        if (CollectionUtils.isEmpty(orderDetails)){
            return null;
        }

        return orderDetails.get(0);
    }

    /**
     * 结算前保存订单明细
     */
    @Override
    public void saveByCost(Long orderId, Long elecPileId, BigDecimal chargeAmount, BigDecimal elecAmount,
                           BigDecimal serviceAmount, BigDecimal soc, BigDecimal power, Date endTime) {

        //查询同一订单的充电记录.
        OrderInfo orderInfo = orderInfoMapper.selectByPrimaryKey(orderId);
        ElecPile elecPile = elecPileMapper.selectByPrimaryKey(elecPileId);

        List<OrderDetail> list = this.queryByOrderId(orderInfo.getOrderId());
        OrderDetail orderDetail = null;
        Date beginDate = null;

        BigDecimal orderRecordBaseAmount = new BigDecimal("0");
        BigDecimal orderRecordChargeAmount = new BigDecimal("0");
        BigDecimal orderRecordServiceAmount = new BigDecimal("0");
        BigDecimal power0 = new BigDecimal("0");

        if (list != null && list.size() > 0) {
            //得到最后一条订单记录
            orderDetail = list.get(0);
            for (OrderDetail orderRecordI : list) {
                orderRecordBaseAmount = orderRecordBaseAmount.add(orderRecordI.getElecAmount());
                orderRecordChargeAmount = orderRecordChargeAmount.add(orderRecordI.getChargeAmount());
                orderRecordServiceAmount = orderRecordServiceAmount.add(orderRecordI.getServiceAmount());
                power0 = power0.add(orderRecordI.getPower());
            }
        }


        if (orderDetail != null) {
            power = power.subtract(power0);
            elecAmount = elecAmount.subtract(orderRecordBaseAmount);
            chargeAmount = chargeAmount.subtract(orderRecordChargeAmount);
            serviceAmount = serviceAmount.subtract(orderRecordServiceAmount);

            //如果是第二个分时段则加一秒
            beginDate = DateHelper.addSecond(orderDetail.getEndTime(), 1);

            //如果是包含三段时间的，加一秒后得到中间的时段时间，判断中间时段是否产生记录，如果没有则新增一条中间分时段
        } else {
            beginDate = orderInfo.getStartTime();
        }

        ElecGun elecGun = elecGunMapper.selectByPrimaryKey(orderInfo.getElecGunId());
        //保存订单开始时间的电价列表，每次都查缓存数据，不受数据库电价改动影响
        //chargePriceHandler.putRedPricesHandler(elecPile.getPileRtua(), elecGun.getGunNum(), orderInfo.getOrderNum(), elecPile.getElecStationId());

        ElecStationPrice elecStationPrice = elecStationPriceService.selectRedValidElecStationPriceByDate(elecPile.getPileRtua(), elecGun.getGunNum(), orderInfo.getOrderNum(), beginDate);

        if (elecStationPrice == null) {
            logger.error("获取电价为空不能结算！！！！！");
            return;
        }


        boolean a = false;
        boolean b = false;
        try {
            a = DateHelper.compareTargerDate(elecStationPrice.getBeginTime(), elecStationPrice.getEndTime(), beginDate);
            b = DateHelper.compareTargerDate(elecStationPrice.getBeginTime(), elecStationPrice.getEndTime(), endTime);
        } catch (ParseException e) {
            logger.error("时间比较出错！,对应订单号:" + orderInfo.getOrderNum());
        }

        //判断开始时间与结束时间是否在同一时段，如果不在同一时段需要分段 否则只生成一条记录
        //如果上一条有记录也不生成两条记录
        if ((a && b)) {
            OrderDetail orderR = new OrderDetail();
            orderR.setBeginTime(beginDate); //开始时间
            orderR.setEndTime(endTime); //结束时间
            orderR.setSoc(soc);     //soc
            orderR.setPower(power); //电量
            orderR.setElecAmount(elecAmount);   //电费
            orderR.setServiceAmount(serviceAmount); //服务费
            orderR.setChargeAmount(elecAmount.add(serviceAmount)); //总金额

            orderR.setElecPrice(elecStationPrice.getElecPrice()); //电费单价
            orderR.setServicePrice(elecStationPrice.getServicePrice()); //服务费单价
            orderR.setOrderId(orderId); //订单ID
            orderR.setCreatedTime(new Date());  //创建时间

            orderR.setMemberId(orderInfo.getMemberId());    //会员ID
            //加入运营商标识
            orderR.setTenantCode(orderInfo.getTenantCode());
            orderR.setOrderNum(orderInfo.getOrderNum());
            orderR.setOutOrderNum(orderInfo.getOutOrderNum());

            orderDetailMapper.insertSelective(orderR);
        } else {
            logger.info("结算生产两条分时段订单记录对应订单号:{}", orderInfo.getOrderNum());
            //获取订单开始时间的结束时段
            Date splitEndDate = DateHelper.splitDateAndTime(beginDate, elecStationPrice.getEndTime());
//            Date splitEndDate = DateHelper.splitDateAndTime(endTime, elecStationPrice.getEndTime());

            //判断分时段的0元时段,距离中间结束时段近的为0元订单分时段。
            long beginLong = splitEndDate.getTime() - beginDate.getTime();
//            long endLong = (endTime.getTime() - splitEndDate.getTime()) < 0 ? -(endTime.getTime() - splitEndDate.getTime()) : (endTime.getTime() - splitEndDate.getTime());
            long endLong = endTime.getTime() - splitEndDate.getTime();



            //根据不同时段，新增一条0元订单
            //ElecStationPrice lastElecPrice = elecStationPriceMapper.queryElecStationPriceByDate(elecStationPrice.getElecStationId(), endTime);
            ElecStationPrice lastElecPrice = elecStationPriceService.selectRedValidElecStationPriceByDate(elecPile.getPileRtua(), elecGun.getGunNum(), orderInfo.getOrderNum(), endTime);

            if (lastElecPrice != null) {
                //订单结束时间的分时段订单
                OrderDetail orderDetail1 = new OrderDetail();
                orderDetail1.setSoc(soc);
                orderDetail1.setOrderId(orderId);
                orderDetail1.setCreatedTime(new Date());
                orderDetail1.setMemberId(orderInfo.getMemberId());
                orderDetail1.setTenantCode(orderInfo.getTenantCode());
                orderDetail1.setOrderNum(orderInfo.getOrderNum());
                orderDetail1.setOutOrderNum(orderInfo.getOutOrderNum());

                //沿用电价开始时段
                Date beginTime = DateHelper.splitDateAndTime(endTime, lastElecPrice.getBeginTime());

                orderDetail1.setBeginTime(beginTime);
                orderDetail1.setEndTime(endTime);
                orderDetail1.setElecPrice(lastElecPrice.getElecPrice());
                orderDetail1.setServicePrice(lastElecPrice.getServicePrice());

                //第二段时段，如果开始时段长则无数据，否则有
                if (beginLong - endLong >= 0) {
                    orderDetail1.setPower(BigDecimal.ZERO);
                    orderDetail1.setElecAmount(BigDecimal.ZERO);
                    orderDetail1.setServiceAmount(BigDecimal.ZERO);
                    orderDetail1.setChargeAmount(BigDecimal.ZERO);
                    orderDetail1.setRemark("1");
                } else {
                    orderDetail1.setRemark("2");
                    orderDetail1.setPower(power);
                    orderDetail1.setElecAmount(elecAmount);
                    orderDetail1.setServiceAmount(serviceAmount);
                    orderDetail1.setChargeAmount(elecAmount.add(serviceAmount));
                }

                orderDetailMapper.insertSelective(orderDetail1);
            }

            //订单开始时间的分时段订单
            OrderDetail orderDetail1 = new OrderDetail();
            orderDetail1.setSoc(soc);
            orderDetail1.setOrderId(orderId);
            orderDetail1.setCreatedTime(new Date());
            orderDetail1.setMemberId(orderInfo.getMemberId());
            orderDetail1.setTenantCode(orderInfo.getTenantCode());
            orderDetail1.setOrderNum(orderInfo.getOrderNum());
            orderDetail1.setOutOrderNum(orderInfo.getOutOrderNum());

            //沿用电价开始时段
            Date endDate = DateHelper.splitDateAndTime(beginDate, elecStationPrice.getEndTime());

            orderDetail1.setBeginTime(beginDate);
            orderDetail1.setEndTime(endDate);
            orderDetail1.setElecPrice(elecStationPrice.getElecPrice());
            orderDetail1.setServicePrice(elecStationPrice.getServicePrice());
            //第一段时段，如果开始时段长则有数据，否则无
            if (beginLong - endLong >= 0) {
                orderDetail1.setPower(power);
                orderDetail1.setElecAmount(elecAmount);
                orderDetail1.setServiceAmount(serviceAmount);
                orderDetail1.setChargeAmount(elecAmount.add(serviceAmount));
                orderDetail1.setRemark("3");
            } else {
                orderDetail1.setPower(BigDecimal.ZERO);
                orderDetail1.setElecAmount(BigDecimal.ZERO);
                orderDetail1.setServiceAmount(BigDecimal.ZERO);
                orderDetail1.setChargeAmount(BigDecimal.ZERO);
                orderDetail1.setRemark("4");
            }
            orderDetailMapper.insertSelective(orderDetail1);
        }


        //判断开始时间是否有产生分时段订单
        int flag = 0;
        List<OrderDetail> orderDetails = this.queryByOrderId(orderInfo.getOrderId());
        if (CollectionUtils.isEmpty(orderDetails)) {
            return;
        }
        for (OrderDetail detail : orderDetails) {
            if (detail.getBeginTime().getTime() <= orderInfo.getStartTime().getTime() && orderInfo.getStartTime().getTime() <= detail.getEndTime().getTime()) {
                return;
            }
        }


        //生产开始时间的分时段订单
        if (flag == 0) {
            //根据不同时段，新增一条0元订单
            //ElecStationPrice beginElecPrice = elecStationPriceMapper.queryElecStationPriceByDate(elecStationPrice.getElecStationId(), endTime);
            ElecStationPrice beginElecPrice = elecStationPriceService.selectRedValidElecStationPriceByDate(elecPile.getPileRtua(), elecGun.getGunNum(), orderInfo.getOrderNum(), endTime);
            if (beginElecPrice == null) {
                return;
            }
            //订单开始时间的分时段订单
            OrderDetail orderDetail1 = new OrderDetail();
            //获取第一条记录的soc
            orderDetail1.setSoc(orderDetails.get(orderDetails.size() - 1).getSoc());
            orderDetail1.setOrderId(orderId);
            orderDetail1.setCreatedTime(new Date());
            orderDetail1.setMemberId(orderInfo.getMemberId());
            orderDetail1.setTenantCode(orderInfo.getTenantCode());
            orderDetail1.setOrderNum(orderInfo.getOrderNum());
            orderDetail1.setOutOrderNum(orderInfo.getOutOrderNum());

            //沿用电价开始时段
            Date endDate = DateHelper.splitDateAndTime(orderInfo.getStartTime(), beginElecPrice.getEndTime());

            orderDetail1.setBeginTime(orderInfo.getStartTime());
            orderDetail1.setEndTime(endDate);
            orderDetail1.setElecPrice(beginElecPrice.getElecPrice());
            orderDetail1.setServicePrice(beginElecPrice.getServicePrice());
            //第一段时段，
            orderDetail1.setPower(BigDecimal.ZERO);
            orderDetail1.setElecAmount(BigDecimal.ZERO);
            orderDetail1.setServiceAmount(BigDecimal.ZERO);
            orderDetail1.setChargeAmount(BigDecimal.ZERO);
            orderDetailMapper.insertSelective(orderDetail1);
        }
    }

    /**
     * 保存充电中分时段数据
     *
     * @param orderId
     * @param cbdto
     * @param elecStationPrice
     * @param elecAmount
     * @param totalAmount
     */
    @Override
    public void saveByCharging(Long orderId, ChargeBalaceDto cbdto, ElecStationPrice elecStationPrice, BigDecimal elecAmount, BigDecimal totalAmount) {
        OrderInfo order = orderInfoMapper.selectByPrimaryKey(orderId);

        //查询同一订单的充电记录.
        List<OrderDetail> list = this.queryByOrderId(orderId);
        OrderDetail orderDetail = null;
        BigDecimal power = new BigDecimal("0");

        Date beginDate = null;
        Date endDate = new Date();

        BigDecimal orderRecordBaseAmount = new BigDecimal("0");
        BigDecimal orderRecordChargeAmount = new BigDecimal("0");
        if (list != null && list.size() > 0) {
            //得到最后一条订单记录
            orderDetail = list.get(0);
            //遍历得到总的电量，金额;
            for (OrderDetail orderRecordI : list) {
                orderRecordBaseAmount = orderRecordBaseAmount.add(orderRecordI.getElecAmount());
                orderRecordChargeAmount = orderRecordChargeAmount.add(orderRecordI.getChargeAmount());
                power = power.add(orderRecordI.getPower());
            }
        }
        //当前电量，金额 减去历史电量金额;
        if (orderDetail != null) {
            power = cbdto.getPower().subtract(power);
            elecAmount = elecAmount.subtract(orderRecordBaseAmount);
            totalAmount = totalAmount.subtract(orderRecordChargeAmount);
            //如果是第二个分时段则加一秒
            beginDate = DateHelper.addSecond(orderDetail.getEndTime(), 1);
            //结束时段需要沿用电价结束时段
            endDate = DateHelper.splitDateAndTime(beginDate, elecStationPrice.getEndTime());

        } else {
            beginDate = order.getStartTime();
            power = cbdto.getPower();

            //结束时段需要沿用电价结束时段
            endDate = DateHelper.splitDateAndTime(beginDate, elecStationPrice.getEndTime());

        }
        //得到服务费
        BigDecimal serviceAmount = totalAmount.subtract(elecAmount);

        //判断开始时间与结束时间是否在同一时段，如果不在同一时段,  则生成一条开始时间的0元分时段。
        boolean a = false;
        boolean b = false;
        try {
            a = DateHelper.compareTargerDate(elecStationPrice.getBeginTime(), elecStationPrice.getEndTime(), beginDate);
            b = DateHelper.compareTargerDate(elecStationPrice.getBeginTime(), elecStationPrice.getEndTime(), endDate);
        } catch (ParseException e) {
            logger.error("时间比较出错！,对应订单号:" + order.getOrderNum());
        }
        //同一时段，只需要生成一条记录
        if ((a && b) || orderDetail != null) {

            OrderDetail orderR = new OrderDetail();
            orderR.setBeginTime(beginDate);
            orderR.setEndTime(endDate);
            orderR.setSoc(cbdto.getSoc());
            orderR.setPower(power);
            orderR.setElecPrice(elecStationPrice.getElecPrice());
            orderR.setServicePrice(elecStationPrice.getServicePrice());
            orderR.setOrderId(orderId);
            orderR.setCreatedTime(new Date());

            orderR.setMemberId(order.getMemberId());
            //加入运营商标识
            orderR.setTenantCode(order.getTenantCode());
            orderR.setOrderNum(order.getOrderNum());
            orderR.setOutOrderNum(order.getOutOrderNum());
            //四舍五入
            orderR.setElecAmount(elecAmount.setScale(2, BigDecimal.ROUND_HALF_UP));
            orderR.setServiceAmount(serviceAmount.setScale(2, BigDecimal.ROUND_HALF_UP));
            orderR.setChargeAmount(orderR.getElecAmount().add(orderR.getServiceAmount()));
            orderDetailMapper.insertSelective(orderR);
        } else {
            logger.info("充电中生产两条分时段订单记录对应订单号:{}", order.getOrderNum());

            ElecPile elecPile = elecPileMapper.selectByPrimaryKey(order.getElecPileId());
            ElecGun elecGun = elecGunMapper.selectByPrimaryKey(order.getElecGunId());

            //新增一条0元订单 前段时间为0元订单
            ElecStationPrice lastElecPrice = elecStationPriceService.selectRedValidElecStationPriceByDate(elecPile.getPileRtua(), elecGun.getGunNum(), order.getOrderNum(), beginDate);
            //ElecStationPrice lastElecPrice = elecStationPriceMapper.queryElecStationPriceByDate(elecStationPrice.getElecStationId(), beginDate);


            OrderDetail orderDetail1 = new OrderDetail();
            orderDetail1.setBeginTime(beginDate);

            //结束时段需要沿用电价结束时段
            Date endTime = DateHelper.splitDateAndTime(endDate, elecStationPrice.getEndTime());

            orderDetail1.setEndTime(endTime);
            orderDetail1.setSoc(cbdto.getSoc());
            orderDetail1.setPower(BigDecimal.ZERO);
            orderDetail1.setElecPrice(lastElecPrice.getElecPrice());
            orderDetail1.setServicePrice(lastElecPrice.getServicePrice());
            orderDetail1.setOrderId(orderId);
            orderDetail1.setCreatedTime(new Date());

            orderDetail1.setMemberId(order.getMemberId());
            //加入运营商标识
            orderDetail1.setTenantCode(order.getTenantCode());
            orderDetail1.setOrderNum(order.getOrderNum());
            orderDetail1.setOutOrderNum(order.getOutOrderNum());
            //四舍五入
            orderDetail1.setElecAmount(BigDecimal.ZERO);
            orderDetail1.setServiceAmount(BigDecimal.ZERO);
            orderDetail1.setChargeAmount(BigDecimal.ZERO);
            orderDetailMapper.insertSelective(orderDetail1);

            OrderDetail orderR = new OrderDetail();

            //将orderDetail1复制到orderR
            try {
                BeanUtil.setBeanByOtherBeanWithoutNull(orderR, orderDetail1);
            } catch (Exception e) {
                e.printStackTrace();
            }

            //如果是第二个分时段则加一秒
            Date beginTime = DateHelper.addSecond(orderDetail1.getEndTime(), 1);
            orderR.setBeginTime(beginTime);
            orderR.setEndTime(endDate);
            //计算有效电费、服务费
            orderR.setElecAmount(elecAmount.setScale(2, BigDecimal.ROUND_HALF_UP));
            orderR.setServiceAmount(serviceAmount.setScale(2, BigDecimal.ROUND_HALF_UP));
            orderR.setChargeAmount(orderR.getElecAmount().add(orderR.getServiceAmount()));
            orderR.setElecPrice(elecStationPrice.getElecPrice());
            orderR.setServicePrice(elecStationPrice.getServicePrice());
            orderR.setCreatedTime(new Date());

            orderDetailMapper.insertSelective(orderR);

        }


    }
}

